package service

import (
	"context"
	"errors"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"gorm.io/gorm"
	"report/global"
	"report/model"
	"report/service/grpc/report"
)

type ReportServiceServer struct {
	report.UnimplementedReportServiceServer
}

func (s *ReportServiceServer) CreateAccount(ctx context.Context, req *report.CreateAccountRequest) (*report.CreateAccountResponse, error) {
	newAccount := &model.Account{
		AccountName:   req.Account.AccountName,
		AccountId:     req.Account.AccountId,
		ProjectId:     req.Account.ProjectId,
		SettingNumber: int(req.Account.SettingNumber),
		Ecpm:          req.Account.Ecpm,
		GameHash:      req.Account.GameHash,
	}

	if err := global.DB.Create(newAccount).Error; err != nil {
		//判断错误是否是唯一索引冲突
		if errors.Is(err, gorm.ErrDuplicatedKey) {
			return nil, status.Errorf(codes.AlreadyExists, "项目id已存在")
		}
	}

	return &report.CreateAccountResponse{
		Id: int64(newAccount.ID),
	}, nil
}

// GetAccount implements the GetAccount RPC method
func (s *ReportServiceServer) GetAccount(ctx context.Context, req *report.GetAccountRequest) (*report.GetAccountResponse, error) {
	var retrievedAccount model.Account
	if err := global.DB.First(&retrievedAccount, req.Id).Error; err != nil {
		return nil, status.Errorf(codes.AlreadyExists, "记录不存在")
	}

	return &report.GetAccountResponse{
		Account: &report.Account{
			Id:            int64(retrievedAccount.ID),
			AccountName:   retrievedAccount.AccountName,
			AccountId:     retrievedAccount.AccountId,
			ProjectId:     retrievedAccount.ProjectId,
			SettingNumber: int64(retrievedAccount.SettingNumber),
			Ecpm:          retrievedAccount.Ecpm,
		},
	}, nil
}

// UpdateAccount implements the UpdateAccount RPC method
func (s *ReportServiceServer) UpdateAccount(ctx context.Context, req *report.UpdateAccountRequest) (*report.UpdateAccountResponse, error) {
	var existingAccount model.Account

	if err := global.DB.First(&existingAccount, req.Account.Id).Error; err != nil {
		return nil, errors.New("记录不存在")
	}

	existingAccount.AccountName = req.Account.AccountName
	existingAccount.AccountId = req.Account.AccountId
	existingAccount.ProjectId = req.Account.ProjectId
	existingAccount.Ecpm = req.Account.Ecpm
	existingAccount.SettingNumber = int(req.Account.SettingNumber)

	global.DB.Model(&existingAccount).Updates(existingAccount)

	return &report.UpdateAccountResponse{
		Id: int64(existingAccount.ID),
	}, nil
}

// DeleteAccount implements the DeleteAccount RPC method
func (s *ReportServiceServer) DeleteAccount(ctx context.Context, req *report.DeleteAccountRequest) (*report.DeleteAccountResponse, error) {
	var existingAccount model.Account

	if err := global.DB.First(&existingAccount, req.Id).Error; err != nil {
		return &report.DeleteAccountResponse{
			Code:    2,
			Message: "记录不存在",
		}, nil
	}

	global.DB.Unscoped().Delete(&existingAccount)

	return &report.DeleteAccountResponse{
		Code:    1,
		Message: "删除成功",
	}, nil
}

// ListAccount ListAccounts implements the ListAccounts RPC method
func (s *ReportServiceServer) ListAccount(ctx context.Context, req *report.ListAccountRequest) (*report.ListAccountResponse, error) {
	var accounts []model.Account

	db := global.DB.Model(&model.Account{})

	db.Where("game_hash = ?", req.GameHash)
	if req.ProjectId != "" {
		db = db.Where("project_id like ?", "%"+req.ProjectId+"%")
	}

	if req.AccountId != "" {
		db = db.Where("account_id = ?", req.AccountId)
	}

	//计算分页
	var total int64
	db.Count(&total)

	start := (req.Page - 1) * 10
	db.Order("id desc").Limit(10).Offset(int(start)).Find(&accounts)

	var accountList []*report.Account
	for _, data := range accounts {
		accountList = append(accountList, &report.Account{
			Id:            int64(data.ID),
			AccountName:   data.AccountName,
			AccountId:     data.AccountId,
			ProjectId:     data.ProjectId,
			SettingNumber: int64(data.SettingNumber),
			Ecpm:          data.Ecpm,
			CreatedAt:     data.CreatedAt.Format("2006-01-02 15:04:05"),
		})
	}
	return &report.ListAccountResponse{
		Accounts: accountList,
		Total:    total,
	}, nil
}

func (g *ReportServiceServer) CreateGameList(ctx context.Context, req *report.CreateGameListRequest) (*report.CreateGameListResponse, error) {
	newAccount := &model.GameList{
		Name:   req.GameList.Name,
		Appid:  req.GameList.Appid,
		Secret: req.GameList.Secret,
	}

	global.DB.Create(newAccount)

	return &report.CreateGameListResponse{
		Id: int64(newAccount.ID),
	}, nil
}

func (g *ReportServiceServer) DeleteGameList(ctx context.Context, req *report.DeleteGameListRequest) (*report.DeleteGameListResponse, error) {
	var existingGame model.GameList

	if err := global.DB.Where("appid = ?", req.Appid).First(&existingGame).Error; err != nil {
		return &report.DeleteGameListResponse{
			Code:    2,
			Message: "记录不存在",
		}, nil
	}

	global.DB.Unscoped().Delete(&existingGame)

	return &report.DeleteGameListResponse{
		Code:    1,
		Message: "删除成功",
	}, nil
}

// ListRetention 留存
func (g *ReportServiceServer) ListRetention(ctx context.Context, req *report.ListRetentionRequest) (*report.ListRetentionResponse, error) {
	var retentions []model.Retention

	db := global.DB.Model(&model.Retention{}).Where("game_hash = ?", req.GameHash)

	if req.Date != "" {
		db = db.Where("date = ?", req.Date)
	}

	//计算分页
	var total int64
	db.Count(&total)

	start := (req.Page - 1) * 10
	db.Order("date desc").Limit(10).Offset(int(start)).Find(&retentions)

	var retentionList []*report.Retention
	for _, data := range retentions {
		retentionList = append(retentionList, &report.Retention{
			Id:          int64(data.ID),
			GameHash:    data.GameHash,
			Date:        data.Date,
			Total:       int64(data.Total),
			TimeRemain:  int64(data.TimeRemain),
			ThreeRemain: int64(data.ThreeRemain),
			FourRemain:  int64(data.FourRemain),
			FiveRemain:  int64(data.FiveRemain),
			SixRemain:   int64(data.SixRemain),
			SevenRemain: int64(data.SevenRemain),
		})
	}

	return &report.ListRetentionResponse{
		Retentions: retentionList,
		Total:      total,
	}, nil
}
